package com.ray.auth.system.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ray.auth.system.emun.LinkType;
import com.ray.auth.system.emun.UseStatus;
import com.ray.auth.system.service.ButtonService;
import com.ray.auth.system.service.MenuService;
import com.ray.auth.system.service.RoleService;
import com.ray.auth.system.table.customMapper.CustomRoleMapper;
import com.ray.auth.system.table.entity.Button;
import com.ray.auth.system.table.entity.Menu;
import com.ray.auth.system.table.entity.Role;
import com.ray.auth.system.table.entity.RoleExample;
import com.ray.auth.system.table.entity.RoleExample.Criteria;
import com.ray.auth.system.table.entity.RoleRel;
import com.ray.auth.system.table.entity.RoleRelExample;
import com.ray.auth.system.table.mapper.RoleMapper;
import com.ray.auth.system.table.mapper.RoleRelMapper;
import com.ray.auth.system.vo.Resource;
import com.ray.auth.system.vo.ResourceButton;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.zjhc.flyhong.common.function.enums.DeleteEnum;
import com.zjhc.flyhong.common.function.exception.BussinessException;
import com.zjhc.flyhong.common.function.operator.LoginUser;
import com.zjhc.flyhong.common.function.operator.PageDto;
import com.zjhc.flyhong.common.function.validate.EntityValidate;
import com.zjhc.flyhong.common.function.validate.rule.FieldRule;
import com.zjhc.flyhong.common.function.validate.rule.RuleEnum;
import com.zjhc.flyhong.common.util.UUIDUtil;
import com.zjhc.flyhong.common.web.ErrorMsg;
import com.zjhc.flyhong.common.web.Result;
import com.zjhc.flyhong.common.web.ResultHelper;
import com.zjhc.flyhong.common.web.SuccessMsg;
import com.zjhc.flyhong.common.web.base.BaseService;
/**
 * <h1>系统权限应用  角色  服务实现</h1>
 * @创建人 ray
 * @创建时间 2017-06-10
 * @版本 1.0
 * @重要修改备注 
 * 
 */
@Service
public class RoleServiceImpl extends BaseService implements RoleService {
	/**日志对象**/
	private static Logger logger = Logger.getLogger(RoleServiceImpl.class);
	/**************实现类  其他对象 引用  开始***********************/
	/**应用数据库操作对象**/
	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private RoleRelMapper roleRelMapper;
	/**菜单关联数据库操作**/
	@Autowired
	private CustomRoleMapper customRoleMapper;
	@Autowired
	private MenuService menuService;
	@Autowired
	private ButtonService buttonService;
	
	 /**
     * 获取用户下所有角色
     * @param userId 用户ID
     * @return 角色ID列表
     */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public List<String> queryRoleByUserId(String userId) {
		List<String> result = new ArrayList<String>();
		for(Role role:this.queryRolesByLinkType(userId, LinkType.USER)){
			result.add(role.getRoleId());
		}
		return result;
	}
	/**
     * 获取用户组下所有角色
     * @param userId 用户ID
     * @return 角色ID列表
     */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public List<String> queryRoleByUserGroupId(String userGroupId) {
		List<String> result = new ArrayList<String>();
		for(Role role:this.queryRolesByLinkType(userGroupId, LinkType.USERGROUP)){
			result.add(role.getRoleId());
		}
		return result;
	}
	
	/**
	 * 通过关联ID和关联类型 获取对应的菜单资源
	 * @param linkId 关联ID
	 * @param linkType 关联类型
	 * @return 菜单资源
	 */ 
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public List<Role> queryRolesByLinkType(String linkId, LinkType linkType) {
	 return customRoleMapper.selectRoleByLink(linkId, linkType.getType(),UseStatus.ON.getType(), DeleteEnum.USE.getValue());
	}
	
	
	/**
	 * 新增角色
	 * @param params 用户对象
	 * @param loginUser 登录用户
	 * @return
	 */
	@Transactional
	public Result<Object> addRole(Role params, LoginUser loginUser){
		//对象验证 
		/*****************验证开始************************/	
		FieldRule fieldRule = new FieldRule();
		fieldRule.addRule(RuleEnum.IS_NOT_NULL, String.class, "roleName","角色名称");
		Result<Object> rs =	EntityValidate.validate(params, fieldRule);
		if(!rs.codeSuccess())return rs;
		/******************验证结束*******************/
		params.setTenantId(loginUser.getTenantId());
		params.setRoleId(UUIDUtil.getUUID());
		params.setIsDelete(DeleteEnum.USE.getValue());
		this.setUserForAdd(params, loginUser);
		//执行成功数量	
		int exeCount = roleMapper.insertSelective(params);
		if(exeCount != 1)return ResultHelper.getError();
		return ResultHelper.getSuccess();
	}
	/**
	 * 查询角色
	 * @param id 角色ID
	 * @param user
	 * @return
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public Role queryRole(String id, LoginUser user){
		return roleMapper.selectByPrimaryKey(id);
	}
	/**
	 * 更新角色信息
	 * @param params 角色信息
	 * @param loginUser
	 * @return
	 */
	@Transactional
	public Result<Object> updateRole(Role params, LoginUser loginUser){
		Result<Object> result = null;
		result = new Result<Object>(0,SuccessMsg.OP_SUCCESS);
		this.setUserForUpdate(params, loginUser);
		int opCount = roleMapper.updateByPrimaryKeySelective(params);
		if(opCount != 1){
			logger.error("RoleServiceImpl=>updateRole is error");
			throw new BussinessException(-1, ErrorMsg.UPDATE_ERROR);
		}
		return result;
	}
	/**
	 * 删除角色
	 * @param id
	 * @param loginUser
	 * @return
	 */
	@Transactional
	public Result<Object> deleteRole(String id, LoginUser loginUser){
		//校验
		FieldRule fieldRule = new FieldRule();
		fieldRule.addObjectIsNotNull("角色编号");
		Result<Object> rs =	EntityValidate.validate(id, fieldRule);
		if(!rs.codeSuccess())return rs;
		
		Result<Object> result = null;
		result = new Result<Object>(0,SuccessMsg.OP_SUCCESS);
		Role record = new Role();
		record.setRoleId(id);
		record.setIsDelete(DeleteEnum.DELETE.getValue());
		this.setUserForUpdate(record, loginUser);
		int opCount = roleMapper.updateByPrimaryKeySelective(record);
		if(opCount != 1){
			logger.error("RoleServiceImpl=>deleteRole is error");
			throw new BussinessException(-1, ErrorMsg.DELETE_ERROR);
		}
		return result;
	}
	/**
	 * 分页查询用户
	 * @param params
	 * @param page
	 * @param loginUser
	 * @return
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public PageDto<Role> queryRoleList(Role params, PageDto<Role> page, LoginUser loginUser){
		RoleExample example = new RoleExample();
		Criteria criteria =  example.createCriteria();
		//超级管理员能看到全部数据
		if(!loginUser.isSuperManager()){
			criteria.andTenantIdEqualTo(loginUser.getTenantId());
		}
		//角色名称模糊查处
		if(StrUtil.isNotBlank(params.getRoleName())){
			criteria.andRoleNameLike(params.getRoleName()+"%");
		}
		//启动状态
		if(StrUtil.isNotBlank(params.getRoleStatus())){
			criteria.andRoleStatusEqualTo(params.getRoleStatus());
		}
		
		criteria.andIsDeleteEqualTo(DeleteEnum.USE.getValue());
		this.setExamplePage(example, page);
		page.setTotal(roleMapper.countByExample(example));
		page.setRecords(roleMapper.selectByExample(example));
		return page;
	}
	
	/**
     * 未拥有的角色查询
     * @param params
     * @param page
     * @param loginUser
     * @return
     */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public PageDto<Role> queryNotHaveRoleList(Role params,String linkId, PageDto<Role> page, LoginUser loginUser){
		RoleExample example = new RoleExample();
		Criteria criteria =  example.createCriteria();
		//超级管理员能看到全部数据
		if(!loginUser.isSuperManager()){
			criteria.andTenantIdEqualTo(loginUser.getTenantId());
		}
		//角色名称模糊查处
		if(StrUtil.isNotBlank(params.getRoleName())){
			criteria.andRoleNameLike(params.getRoleName()+"%");
		}
		criteria.andRoleStatusEqualTo(UseStatus.ON.getType());
		criteria.andIsDeleteEqualTo(DeleteEnum.USE.getValue());
		this.setExamplePage(example, page);
		page.setTotal(customRoleMapper.countNotHaveRole(linkId, LinkType.USER.getType(),
				DeleteEnum.USE.getValue(), example));
		page.setRecords(customRoleMapper.selectNotHaveRole(linkId, LinkType.USER.getType(), 
				DeleteEnum.USE.getValue(), example));
		return page;
	}
    /**
     * 拥有的角色查询
     * @param params
     * @param page
     * @param loginUser
     * @return
     */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public PageDto<Role> queryHaveRoleList(Role params, String linkId,PageDto<Role> page, LoginUser loginUser){
		RoleExample example = new RoleExample();
		Criteria criteria =  example.createCriteria();
		//超级管理员能看到全部数据
		if(!loginUser.isSuperManager()){
			criteria.andTenantIdEqualTo(loginUser.getTenantId());
		}
		//角色名称模糊查处
		if(StrUtil.isNotBlank(params.getRoleName())){
			criteria.andRoleNameLike(params.getRoleName()+"%");
		}
		criteria.andRoleStatusEqualTo(UseStatus.ON.getType());
		criteria.andIsDeleteEqualTo(DeleteEnum.USE.getValue());
		this.setExamplePage(example, page);
		page.setTotal(customRoleMapper.countHaveRole(linkId, LinkType.USER.getType(),
				DeleteEnum.USE.getValue(), example));
		page.setRecords(customRoleMapper.selectHaveRole(linkId, LinkType.USER.getType(), 
				DeleteEnum.USE.getValue(), example));
		return page;
	}
	
	 /**
     * 新增角色 关联
     * @param id 角色ID
     * @param type 关联类型
     * @param loginUser
     * @return
     */
	@Transactional
	public Result<Object> addRoleRel(String roleId,String linkId,String linkType, LoginUser loginUser){
		//校验
		EntityValidate.isNotNull(roleId,"角色编号");
		EntityValidate.isNotNull(linkId,"关联编号");
		EntityValidate.isNotNull(linkType,"关联类型");
		/******************验证结束*******************/
		RoleRel params = new RoleRel();
		params.setId(UUIDUtil.getUUID());
		params.setTenantId(loginUser.getTenantId());
		params.setRoleId(roleId);
		params.setLinkId(linkId);
		params.setLinkType(linkType);
		params.setIsDelete(DeleteEnum.USE.getValue());
		this.setUserForAdd(params, loginUser);
		//执行成功数量	
		int exeCount = roleRelMapper.insertSelective(params);
		if(exeCount != 1)return ResultHelper.getError();
		return ResultHelper.getSuccess();
	}
	/**
     * 删除角色 关联
     * @param id 角色ID
     * @param type 关联类型
     * @param loginUser
     * @return
     */
	@Transactional
	public Result<Object> deleteRoleRel(String roleId,String linkId,String linkType, LoginUser loginUser){
		Result<Object> result = null;
		//校验
		EntityValidate.isNotNull(roleId,"角色编号");
		EntityValidate.isNotNull(linkId,"关联编号");
		EntityValidate.isNotNull(linkType,"关联类型");
		result = new Result<Object>(0,SuccessMsg.OP_SUCCESS);
		RoleRel record = new RoleRel();
		record.setIsDelete(DeleteEnum.DELETE.getValue());
		RoleRelExample example = new RoleRelExample();
		example.createCriteria().andRoleIdEqualTo(roleId)
		.andLinkIdEqualTo(linkId).andLinkTypeEqualTo(linkType)
		.andIsDeleteEqualTo(DeleteEnum.USE.getValue());
		this.setUserForUpdate(record, loginUser);
		int opCount = roleRelMapper.updateByExampleSelective(record, example);
		if(opCount != 1){
			logger.error("RoleServiceImpl=>deleteRoleRel is error");
			throw new BussinessException(-1, ErrorMsg.DELETE_ERROR);
		}
		return result;
	}
	
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public List<Resource> queryRoleResource(String menuId, String roleId, LoginUser user) {
		List<Resource> rsList = new ArrayList<Resource>(); 
		Resource resource = null;
		//根据菜单编号获取下级菜单
		List<Menu> menus = menuService.queryChildMenuList(menuId,user);
		List<Button> buttons = null;
		List<ResourceButton> resButtons = null;
		Map<String,Menu> userOnwerMenus  = null;
		Map<String,Object> roleOnwerMenus  = null;
		Map<String,Button> userOnwerButtons  = null;
		Map<String,Object> roleOnwerButtons  = null;
		//不是超级管理员获取用户拥有的菜单和按钮
		if(!user.isSuperManager()){
			userOnwerMenus = queryUserOnwerMenus(user.getUserId(),user);
			userOnwerButtons = queryUserOnwerButtons(user.getUserId(),user);
		}
		//获取角色对应的菜单
		roleOnwerMenus = queryRoleOnwerMenus(roleId,user);
		//获取角色对应的按钮
		roleOnwerButtons = queryRoleOnwerButons(roleId,user);
		//通过菜单查询按钮
		for(Menu menu:menus){
			//设置资源对象
			resource = new Resource();
			resource.setMenu(menu);
			//设置菜单是否科授权
			if(user.isSuperManager()){
				resource.setRead(false);
			}else{
				//判断用户是否拥有这个菜单 
				if(ObjectUtil.isNull(userOnwerMenus.get(menu.getMenuId()))){
					resource.setRead(true);//没有读取的权限
				}else{
					resource.setRead(false);	
				}
			}
			//设置菜单是否科授权
			if(ObjectUtil.isNull(roleOnwerMenus.get(menu.getMenuId()))){
				resource.setCheck(false);//没有权限
			}else{
				resource.setCheck(true);//有权限
			}
			//设置菜单授权状态
			buttons = buttonService.queryButtonsByMenuId(menu.getMenuId(),null);
			ResourceButton rButton = null;
			resButtons = new ArrayList<ResourceButton>();
			for(Button button :buttons){
				rButton = new ResourceButton();
				rButton.setButton(button);
				
				//设置菜单是否科授权
				if(user.isSuperManager()){
					rButton.setRead(false);
				}else{
					//判断用户是否拥有这个菜单 
					if(ObjectUtil.isNull(userOnwerButtons.get(button.getButtonId()))){
						rButton.setRead(true);//没有读取的权限
					}else{
						rButton.setRead(false);	
					}
				}
				//设置菜单是否科授权
				if(ObjectUtil.isNull(roleOnwerButtons.get(button.getButtonId()))){
					rButton.setCheck(false);//没有权限
				}else{
					rButton.setCheck(true);//有权限
				}
				resButtons.add(rButton);
			}
			resource.setButtons(resButtons);
			//设置下级菜单
			//resource.setChild(queryRoleResource(menu.getMenuId(), roleId, user));
			rsList.add(resource);
		}
		return rsList;
	}
	/**
	 * 获取角色拥有的按钮
	 * @param roleId
	 * @param user
	 * @return
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	private Map<String, Object> queryRoleOnwerButons(String roleId, LoginUser user) {
		List<Button> buttons = buttonService.queryRoleOnwerButtons(roleId,user);
		Map<String,Object> map = new HashMap<String,Object>();
		for(Button button:buttons){
			map.put(button.getButtonId(), button);
		}
		return map;
	}
	/**
	 * 用户拥有的按钮资源
	 * @param userId
	 * @param user
	 * @return
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	private Map<String, Button> queryUserOnwerButtons(String userId, LoginUser user) {
		List<Button> buttons = buttonService.queryUserOnwerButtons(userId,user);
		Map<String,Button> map = new HashMap<String,Button>();
		for(Button button:buttons){
			map.put(button.getButtonId(), button);
		}
		return map;
	}
	/**
	 * 获取角色对应的菜单
	 * @param roleId
	 * @param user
	 * @return
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	private Map<String,Object> queryRoleOnwerMenus(String roleId, LoginUser user) {
		List<Menu> menus = menuService.queryRoleOnwerMenus(roleId, user);
		Map<String,Object> map = new HashMap<String,Object>();
		for(Menu menu:menus){
			map.put(menu.getMenuId(), menu);
		}
		return map;
	}
	/**
	 * 获取用户拥有的菜单
	 * @param userId
	 * @return
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	private Map<String,Menu> queryUserOnwerMenus(String userId,LoginUser user) {
		List<Menu> menus = menuService.queryUserOnwerMenus(userId,user);
		Map<String,Menu> map = new HashMap<String,Menu>();
		for(Menu menu:menus){
			map.put(menu.getMenuId(), menu);
		}
		return map;
	}
	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public List<Role> queryRole(List<String> ids) {
		RoleExample example = new RoleExample();
		example.createCriteria().andRoleIdIn(ids);
		return roleMapper.selectByExample(example);
	}
	
}
